package com.service.component.log.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.service.component.common.utils.CommonUtils;
import com.service.component.log.entity.SysOperate;
import com.service.component.log.services.SysOperateService;
import com.service.component.user.entity.Users;
import com.service.component.user.services.UserServices;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.time.LocalTime;
import java.util.Date;

@Slf4j
@Aspect
@Component
/**
 * @author ：Calvin
 * @date ：Created in 2021/7/16 14:35
 * @description：全局操作日志处理
 * @modified By：
 * @version: 1.0.0$
 */
public class SysOperateAspect {

    @Autowired
    private SysOperateService sysOperateService;

    @Autowired
    private UserServices userServices;

    /**
     * 定义切点@Pointcut
     * 在注解的位置切入代码
     */
    @Pointcut("@annotation(com.service.component.log.aspect.SysOperateLog)")
    public void sysOpseratePointCut() {
    }


    @AfterReturning(value = "sysOpseratePointCut()", returning = "resultVals")
    public void saveSysOperateLog(JoinPoint joinPoint, Object resultVals) {
        log.info("切面。。。");
        SysOperate sysOperate = new SysOperate();

        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        //获取切入点所在的方法
        Method method = signature.getMethod();

        SysOperateLog sysOperateLog = method.getAnnotation(SysOperateLog.class);
        if (ObjectUtils.isNotEmpty(sysOperateLog)) {
            sysOperate.setOperateType(sysOperateLog.operateType().getOperateType());
            sysOperate.setOperateDescrption(sysOperateLog.descrption());
        }

        //操作应用Id
        //TODO
        sysOperate.setOperateApplicationId("common");
        //获取请求类名
        String className = joinPoint.getTarget().getClass().getName();
        //获取方法名
        String methodName = method.getName();
        sysOperate.setOperateMethod(className + "." + methodName);
        //请求参数
        Object[] args = joinPoint.getArgs();
        String params = JSON.toJSONString(args);
        sysOperate.setParams(params);

        //操作人员
        Subject subject = SecurityUtils.getSubject();
        Users user = ObjectUtils.isNotEmpty(subject.getPrincipals()) ? subject.getPrincipals().oneByType(Users.class) : new Users();
        if (StringUtils.endsWithIgnoreCase("register", methodName)) {
            user = JSON.parseObject(JSON.toJSONString(args[0]), Users.class);
            if (StringUtils.isEmpty(user.getCreatoNo())) {
                user = userServices.getUserByUsername(user.getUsername());
            }
        }
        sysOperate.setOperateor(ObjectUtils.isNotEmpty(user) ? user.getUsername() : "");
        sysOperate.setCreatoNo(ObjectUtils.isNotEmpty(user) ? ObjectUtils.isNotEmpty(user.getCreatoNo()) ? user.getCreatoNo() : "" : "");
        sysOperate.setModifierNo(ObjectUtils.isNotEmpty(user) ? ObjectUtils.isNotEmpty(user.getCreatoNo()) ? user.getCreatoNo() : "" : "");
        //返回结果
        sysOperate.setOperateResult(JSON.toJSONString(resultVals));
        //操作IP
        sysOperate.setOperateIp(CommonUtils.getIpAddr());

        log.info("日志数据" + sysOperate.toString());
        if (StringUtils.isNotEmpty(sysOperate.getOperateor())) sysOperateService.insert(sysOperate);
    }
}
